home *** CD-ROM | disk | FTP | other *** search
- Unit Bitmap;
-
- {
- Bitmap handling routines, v4.12
- by Maple Leaf, 1995-96
- ----------------------------------
- Supported formats:
- Load: BMP,TGA,EST,LBM,PIC,PCX,BIN
- Save: BMP,TGA,EST,LBM,BIN
- }
-
- Interface
-
- Uses alloc, Files, FCache, XMS;
-
- Const
- BitMapError : Byte = 0;
-
- { Quick utils }
- Procedure ShowPic(PicPtr:Pointer);
-
- { XMS-ed bitmaps handling }
- Procedure MovePicToXMS(PalPtr:Pointer; var PicPtr:Pointer; var Handle:word);
- Procedure CopyPicToXMS(PalPtr,PicPtr:Pointer; var Handle:word);
- Procedure CopyPicFromXMS(PalPtr:pointer; var PicPtr:Pointer; var Handle:word);
- Procedure MovePicFromXMS(PalPtr:pointer; var PicPtr:Pointer; var Handle:word);
-
- { Load }
- Function LoadEST(FileName:String; PalPtr:Pointer) : Pointer;
- Function LoadBMP(FileName:String; PalPtr:Pointer) : Pointer;
- Function LoadTGA(FileName:String; PalPtr:Pointer) : Pointer;
- Function LoadBIN(FileName:String; PalPtr:Pointer) : Pointer;
- Function LoadLBM(FileName:String; PalPtr:Pointer) : Pointer; { only the "PBM " format supported }
- Function LoadPIC(FileName:String; PalPtr:Pointer) : Pointer;
- Function LoadPCX(FileName:String; PalPtr:Pointer) : Pointer;
-
- { Overlayed EST loader }
- Function LoadESTFromFile(var f:File; PalPtr:Pointer) : Pointer;
-
- { Save }
- Procedure SaveEST(FileName:String; PalPtr,PicPtr:Pointer);
- Procedure SaveBMP(FileName:String; PalPtr,PicPtr:Pointer);
- Procedure SaveTGA(FileName:String; PalPtr,PicPtr:Pointer);
- Procedure SaveBIN(FileName:String; PalPtr,PicPtr:Pointer);
- Procedure SaveLBM(FileName:String; PalPtr,PicPtr:Pointer); { only the "PBM " format supported }
-
- Implementation
-
- Procedure ShowPic(PicPtr:Pointer);assembler;
- asm
- push ds
- mov cx,16000
- mov di,0a000h
- mov es,di
- xor di,di
- lds si,dword ptr PicPtr
- cld
- db 66h; rep movsw
- pop ds
- end;
-
- Function LoadBMP(FileName:String; PalPtr:Pointer) : Pointer;
- Var
- f:file; p:pointer;
- z:byte;
- lin,k,col:longint;
- xx,yy,r:word;
- _xx : word;
- bb:byte;
- begin {$i-}
- BitMapError:=0; LoadBMP:=nil;
- if not OpenForInput(f,FileName) then begin
- BitMapError:=1;
- Exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- p:=malloc(64000);
- fillchar(p^,64000,0);
- seek(f,$12); BlockRead(f,xx,2,r);
- seek(f,$16); BlockRead(f,yy,2,r);
- _xx:=(FileSize(f)-1077) div yy;
- if yy>200 then yy:=200;
- Seek(f,$36);
- ResetBuffer;
- for k:=0 to 255 do begin
- Mem[seg(PalPtr^):ofs(PalPtr^)+k*3+2]:=ReadByte(f) shr 2;
- Mem[seg(PalPtr^):ofs(PalPtr^)+k*3+1]:=ReadByte(f) shr 2;
- Mem[seg(PalPtr^):ofs(PalPtr^)+k*3+0]:=ReadByte(f) shr 2;
- z:=ReadByte(f);
- end;
- {if not center then begin
- lin:=yy; col:=0;
- end else begin}
- lin:=100+(yy div 2);
- col:=160-(_xx div 2);
- {end;}
- repeat
- dec(lin);
- for k:=0 to _xx-1 do begin
- bb:=ReadByte(f);
- if k+1>xx then
- Mem[seg(p^):ofs(p^)+(lin*320)+k+col]:=0
- else
- Mem[seg(p^):ofs(p^)+(lin*320)+k+col]:=bb;
- end;
- until lin=0;
- CloseFile(f);
- LoadBMP:=p;
- end;
-
- Procedure SaveBMP(FileName:String; PalPtr,PicPtr:Pointer);
- var
- f:file; r:word;
- k : word;
- lulu : word;
- PalBMP : array [0..255] of record b, g, r, z: byte end;
- Offset:word;
- lin:word;
- Const
- BMP_Header : Array [0..$35] of byte = ( $42, $4d, $36, $fe, 0, 0, 0, 0, 0, 0, $36, 4, 0, 0, $28, 0, 0, 0,
- $40, 1, 0, 0, $c8, 0, 0, 0, 1, 0, 8, 0, 0, 0, 0, 0, 0, $fa, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
- begin {$i-}
- BitMapError:=0;
- if not OpenForOutput(f,FileName) then begin
- BitMapError:=5;
- end;
- BlockWrite(f,BMP_Header,SizeOf(BMP_Header)); { Writing BMP header }
- OutBuffIndex:=0;
- { Writing palette }
- for k:=0 to 255 do begin
- PalBMP[k].r:=mem[seg(PalPtr^):ofs(PalPtr^)+k*3];
- PalBMP[k].g:=mem[seg(PalPtr^):ofs(PalPtr^)+k*3+1];
- PalBMP[k].b:=mem[seg(PalPtr^):ofs(PalPtr^)+k*3+2];
- PalBMP[k].z:=0;
- WriteByte(f,PalBMP[k].b shl 2);
- WriteByte(f,PalBMP[k].g shl 2);
- WriteByte(f,PalBMP[k].r shl 2);
- WriteByte(f,PalBMP[k].z shl 2);
- end;
- FlushBuffer(f);
- lin:=200;
- OutBuffIndex:=0;
- repeat
- dec(lin);
- for k:=0 to 319 do WriteByte(f,Mem[seg(PicPtr^):ofs(PicPtr^)+(lin*320)+k]);
- until lin=0;
- FlushBuffer(f);
- CloseFile(f);
- end;
-
- Function LoadTGA(FileName:String; PalPtr:Pointer) : Pointer;
- Var
- f:file; r:word; p:pointer;
- lin,k : word;
- Offset : word;
- ImageType : Byte;
- TGA_Head : record a,b,c:longint; DimX, DimY:Word; Pad,ImgType:byte end;
- begin {$i-}
- BitMapError:=0; LoadTGA:=nil;
- if not OpenForInput(f,FileName) then begin
- BitMapError:=1; { File not found }
- exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- p:=malloc(64000);
- fillchar(p^,64000,0);
- Seek(f,0);
- ResetBuffer;
- BlockRead(f,TGA_Head,18,k);
- ImageType:=TGA_Head.ImgType;
- for k:=0 to 255 do begin
- mem[seg(PalPtr^):ofs(PalPtr^)+k*3+2]:=ReadByte(f) shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+k*3+1]:=ReadByte(f) shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+k*3+0]:=ReadByte(f) shr 2;
- end;
- Seek(f,18+256*3);
- if ImageType=$20 then begin
- lin:=0;
- repeat
- BlockRead(f,mem[seg(p^):ofs(p^)+lin*320],TGA_Head.DimX,k);
- inc(lin);
- until lin=TGA_Head.DimY;
- end else begin
- lin:=TGA_Head.DimY;
- repeat
- dec(lin);
- BlockRead(f,mem[seg(p^):ofs(p^)+lin*320],TGA_Head.DimX,k);
- until lin=0;
- end;
- CloseFile(f);
- LoadTGA:=p;
- end;
-
- Procedure SaveTGA(FileName:String; PalPtr,PicPtr:Pointer);
- var fo:file; r:word; sgn:string[3];
- TGAp : Array [byte] of record b,g,r:byte end;
- const
- TGA_Header:array [0..17] of byte = ( 0,1,1,0,0,0,1,$18,0,0,0,0,$40,1,$c8,0,8,$20 );
- begin {$i-}
- BitMapError:=0;
- if not OpenForOutput(fo,FileName) then begin
- BitMapError:=5; { Cannot create file }
- exit;
- end;
- BlockWrite(fo,TGA_Header,18); { Writing TGA header }
- for r:=0 to 255 do begin
- TGAp[r].r:=mem[seg(PalPtr^):ofs(PalPtr^)+r*3] shl 2;
- TGAp[r].g:=mem[seg(PalPtr^):ofs(PalPtr^)+r*3+1] shl 2;
- TGAp[r].b:=mem[seg(PalPtr^):ofs(PalPtr^)+r*3+2] shl 2;
- end;
- BlockWrite(fo,TGAp,768,r);
- if r<768 then begin
- BitMapError:=6; { Disk full }
- CloseFile(fo);
- exit;
- end;
- BlockWrite(fo,PicPtr^,64000,r);
- if r<64000 then begin
- BitMapError:=6; { Disk full }
- CloseFile(fo);
- exit;
- end;
- CloseFile(fo);
- end;
-
- Function LoadEST(FileName:String; PalPtr:Pointer) : Pointer;
- type
- ESTHType = record
- Sign : LongInt; { Signature 'ExST'}
- RevisionNo : Byte; { Revision number (version) }
- ImageType : Byte; { 0=Text, 1=BitMap, 2=Vect }
- XDim,YDim : Word; { Dimensions }
- HRes : Word; { Original Horiz. resolution }
- VRes : Word; { Orig. vert. resolution }
- BpColors : Word; { Bits/color (usually 8 or 4) }
- Encode : Byte; { Compression method (0,1,2,3) }
- ImageOffs : Word; { Image's start offset }
- ImageInfo : String[80]; { Image informations }
- { Here might be other infos ... }
- { ... }
- end;
- var k:word; f:file; p:pointer; EST_Header:ESTHType;
- Procedure UnCompressRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin {$i-}
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f); Last:=ReadByte(f);
- Counter:=0;
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- Procedure UnCompressHRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f);
- if NrOf>0 then begin { then it's a compressed block }
- Last:=ReadByte(f);
- Counter:=0;
- { Uncompressing block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end else begin { it's an uncompressed block }
- NrOf:=ReadByte(f);
- Counter:=0;
- { Extracting the uncompressed block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=ReadByte(f);
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- Procedure UnCompressXRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f);
- if ShortInt(NrOf)>0 then begin { then it's a compressed block }
- Last:=ReadByte(f);
- Counter:=0;
- { Uncompressing block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end else begin { it's an uncompressed block }
- NrOf:=Byte(-ShortInt(NrOf));
- Counter:=0;
- { Extracting the uncompressed block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=ReadByte(f);
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- begin {$i-}
- BitMapError:=0; LoadEST:=nil;
- if not OpenForInput(f,FileName)then begin
- BitMapError:=1; { File not found }
- exit;
- end;
- p:=malloc(64016);
- if p=nil then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- fillchar(p^,64000,0);
- BlockRead(f,EST_Header,SizeOf(EST_Header),k); { Citeste header }
- if EST_Header.Sign<>$54537845 then begin
- CloseFile(f);
- BitMapError:=3; { Invalid format }
- Free(p);
- exit;
- end;
- BlockRead(f,PalPtr^,768,k);
- if k<768 then begin
- CloseFile(f);
- BitMapError:=4; { Corrupted picture }
- Free(p);
- exit;
- end;
- Seek(f,EST_Header.ImageOffs);
- case EST_Header.Encode of
- 0: BlockRead(f,p^,64000,k); { No encoded }
- 1: UncompressRLE(f); { Run-Length Encoded }
- 2: UncompressHRLE(f); { Hard Run-Length Encoded }
- 3: UncompressXRLE(f); { Extra Run-Length Encoded }
- end;
- CloseFile(f);
- LoadEST:=p;
- end;
-
- Function LoadESTFromFile(var f:file; PalPtr:Pointer) : Pointer;
- type
- ESTHType = record
- Sign : LongInt; { Signature 'ExST'}
- RevisionNo : Byte; { Revision number (version) }
- ImageType : Byte; { 0=Text, 1=BitMap, 2=Vect }
- XDim,YDim : Word; { Dimensions }
- HRes : Word; { Original Horiz. resolution }
- VRes : Word; { Orig. vert. resolution }
- BpColors : Word; { Bits/color (usually 8 or 4) }
- Encode : Byte; { Compression method (Not=0) }
- ImageOffs : Word; { Image's start offset }
- ImageInfo : String[80]; { Image informations }
- { Here might be other infos ... }
- { ... }
- end;
- var k:word; p:pointer; EST_Header:ESTHType; origpos:longint;
- Procedure UnCompressRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin {$i-}
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f); Last:=ReadByte(f);
- Counter:=0;
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- Procedure UnCompressHRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f);
- if NrOf>0 then begin { then it's a compressed block }
- Last:=ReadByte(f);
- Counter:=0;
- { Uncompressing block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end else begin { it's an uncompressed block }
- NrOf:=ReadByte(f);
- Counter:=0;
- { Extracting the uncompressed block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=ReadByte(f);
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- Procedure UnCompressXRLE(var f:file);
- Var
- XD : word;
- Offset : Word;
- NrOf,Last : Byte;
- Counter : byte;
- begin
- Offset:=0;
- ResetBuffer;
- Repeat
- NrOf:=ReadByte(f);
- if ShortInt(NrOf)>0 then begin { then it's a compressed block }
- Last:=ReadByte(f);
- Counter:=0;
- { Uncompressing block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=Last;
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end else begin { it's an uncompressed block }
- NrOf:=Byte(-ShortInt(NrOf));
- Counter:=0;
- { Extracting the uncompressed block ... }
- Repeat
- if offset<64000 then Mem[seg(p^):ofs(p^)+Offset]:=ReadByte(f);
- Inc(Counter);
- inc(Offset);
- if Offset mod EST_Header.XDim = 0 then
- Offset:=Offset+EST_Header.HRes-EST_Header.XDim;
- Until Counter=NrOf;
- end;
- Until (Offset>64000) or (InBuffIndex=0);
- end;
- begin {$i-}
- BitMapError:=0; LoadESTFromFile:=nil;
- OrigPos:=FilePos(f);
- p:=malloc(64016);
- if p=nil then begin
- BitMapError:=2; { Not enough memory }
- exit;
- end;
- fillchar(p^,64000,0);
- BlockRead(f,EST_Header,SizeOf(EST_Header),k); { Citeste header }
- if EST_Header.Sign<>$54537845 then begin
- BitMapError:=3; { Invalid format }
- Free(p);
- exit;
- end;
- BlockRead(f,PalPtr^,768,k);
- if k<768 then begin
- BitMapError:=4; { Corrupted picture }
- Free(p);
- exit;
- end;
- Seek(f,OrigPos+LongInt(EST_Header.ImageOffs));
- case EST_Header.Encode of
- 0: BlockRead(f,p^,64000,k); { No encoded }
- 1: UncompressRLE(f); { Run-Length Encoded }
- 2: UncompressHRLE(f); { Hard Run-Length Encoded }
- 3: UncompressXRLE(f); { Extra Run-Length Encoded }
- end;
- LoadESTFromFile:=p;
- end;
-
- Procedure SaveEST(FileName:String; PalPtr,PicPtr:Pointer);
- type
- ESTHType = record
- Sign : LongInt; { Signature 'ExST'}
- RevisionNo : Byte; { Revision number (version) }
- ImageType : Byte; { 0=Text, 1=BitMap, 2=Vect }
- XDim,YDim : Word; { Dimensions }
- HRes : Word; { Original Horiz. resolution }
- VRes : Word; { Orig. vert. resolution }
- BpColors : Word; { Bits/color (usually 8 or 4) }
- Encode : Byte; { Compression method (None=0) }
- ImageOffs : Word; { Image's start offset }
- ImageInfo : String[80]; { Image informations }
- { Here might be other infos ... }
- { ... }
- end;
- var fo:file; r:word;
- k:word;
- EST_Header:ESTHType;
- Last:Byte;
- NrOf:Word;
- Offset,AuxOffset:Word;
- begin {$i-}
- if not OpenForOutput(fo,FileName) then begin
- BitMapError:=5; { Cannot create file }
- exit;
- end;
- fillchar(EST_Header,sizeof(EST_Header),0);
- with EST_Header do begin
- Sign:=$54537845; { 'ExST' }
- ImageType:=1;
- RevisionNo:=4;
- XDim:=320; YDim:=200;
- HRes:=320; VRes:=200;
- BpColors:=8;
- Encode:=3; { Extra Run Length Encoding }
- ImageOffs:=SizeOf(EST_Header)+768;
- ImageInfo:='Bitmap library v4.12, by Maple Leaf, 1996';
- end;
- BlockWrite(fo,EST_header,SizeOf(EST_Header),k);
- BlockWrite(fo,PalPtr^,768,k);
- Offset:=0;
- OutBuffIndex:=0;
- repeat
- Last:=Mem[seg(PicPtr^):Ofs(PicPtr^)+Offset];
- NrOf:=0;
- while (mem[seg(PicPtr^):ofs(PicPtr^)+Offset]=Last) and (Offset<64000) and (NrOf<$7F) do begin
- inc(NrOf); Inc(Offset);
- end;
- if NrOf<2 then begin
- AuxOffset:=Offset-1;
- Last:=Mem[seg(PicPtr^):ofs(PicPtr^)+AuxOffset];
- NrOf:=1;
- while (Last<>Mem[seg(PicPtr^):ofs(PicPtr^)+Offset]) and (Offset<64000) and (NrOf<$80) do begin
- inc(NrOf);
- Last:=Mem[seg(PicPtr^):ofs(PicPtr^)+Offset];
- inc(Offset);
- end;
- if (mem[seg(PicPtr^):ofs(PicPtr^)+Offset-1]=mem[seg(PicPtr^):ofs(PicPtr^)+Offset]) and
- (Offset<=64000) and (NrOf<=$80) then begin
- dec(Offset);
- dec(NrOf); { Keeps the latest byte for a new check }
- end;
- WriteByte(fo,Byte(ShortInt(-NrOf))); { Size of uncompressed block }
- { Write the uncompressed block ... }
- for k:=0 to NrOf-1 do WriteByte(fo,Mem[seg(PicPtr^):Ofs(PicPtr^)+AuxOffset+k]);
- end else begin
- WriteByte(fo,NrOf); { Size of compressed block }
- WriteByte(fo,Last); { Char to fill with }
- end;
- until (Offset>=64000);
- FlushBuffer(fo);
- if FileSize(fo)>64000+SizeOf(EST_Header)+768 then begin
- { Compression wasn't efficient, so just store the image as it is }
- with EST_Header do begin
- Sign:=$54537845; { 'ExST' }
- ImageType:=1;
- RevisionNo:=4;
- XDim:=320; YDim:=200;
- HRes:=320; VRes:=200;
- BpColors:=8;
- Encode:=0; { No encoding }
- ImageOffs:=SizeOf(EST_Header)+768;
- ImageInfo:='Bitmap library v4.12, by Maple Leaf, 1996';
- end;
- Seek(fo,0);
- BlockWrite(fo,EST_Header,sizeof(EST_Header),r);
- BlockWrite(fo,PalPtr^,768,k);
- BlockWrite(fo,PicPtr^,64000,k);
- Truncate(fo);
- end;
- CloseFile(fo);
- end;
-
- Function LoadBIN(FileName:String; PalPtr:Pointer) : Pointer;
- var fi:file;
- p:pointer;
- r:word;
- begin {$i-}
- BitMapError:=0; LoadBIN:=nil;
- if not OpenForInput(fi,FileName) then begin
- BitMapError:=1; { File not found }
- exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(fi);
- exit;
- end;
- BlockRead(fi,PalPtr^,768,r);
- if r<768 then begin
- BitMapError:=4; { Corrupted picture }
- CloseFile(fi);
- exit;
- end;
- p:=malloc(64000);
- FillChar(p^,64000,0);
- BlockRead(fi,p^,64000,r);
- if r<64000 then begin
- BitMapError:=4; { Corrupted picture }
- Free(p);
- CloseFile(fi);
- exit;
- end;
- CloseFile(fi);
- LoadBIN:=p;
- end;
-
- Procedure SaveBIN(FileName:String; PalPtr,PicPtr:Pointer);
- var fo:file; r:word; sgn:string[3];
- begin {$i-}
- BitMapError:=0;
- if not OpenForOutput(fo,FileName) then begin
- BitMapError:=5; { Cannot create file }
- exit;
- end;
- BlockWrite(fo,PalPtr^,768,r);
- if r<768 then begin
- BitMapError:=6; { Disk full }
- CloseFile(fo);
- exit;
- end;
- BlockWrite(fo,PicPtr^,64000,r);
- if r<64000 then begin
- BitMapError:=6; { Disk full }
- CloseFile(fo);
- exit;
- end;
- CloseFile(fo);
- end;
-
- Function SwapLong(n:longint):longint;assembler;
- asm
- mov ax,word ptr n+2
- mov dx,word ptr n
- xchg al,ah
- xchg dl,dh
- end;
-
- Function LoadLBM(FileName:String; PalPtr:Pointer) : Pointer;
- type
- FORM_chunk = record ckID, CkSize, SubType : LongInt end;
- Chunk = record ckID, ckSize : LongInt end;
- LBMHeader = record
- DimX, DimY, PosX, PosY : Word;
- Planes, Masking, Compression, Pad1 : Byte;
- TranspCol : Word;
- xAspect, yAspect : Byte;
- PageWidth, PageHeight : Word;
- end;
- const
- LBM_FORM = $4D524F46; { 'FORM' }
- LBM_ILBM = $4D424C49; { 'ILBM' }
- LBM_BMHD = $44484D42; { 'BMHD' }
- LBM_CMAP = $50414D43; { 'CMAP' }
- LBM_BODY = $59444F42; { 'BODY' }
- LBM_TEXT = $54584554; { 'TEXT' }
- LBM_PBM = $204D4250; { 'PBM ' }
- var
- Pal:Array[byte] of record r,g,b:byte end;
- f:file; p:pointer;
- chk:Chunk;
- fc:FORM_chunk;
- bh:LBMHeader;
- r:word;
- Gata:boolean;
- Offset:Word;
- Value:ShortInt; SoFar,Len,Count:Integer;
- begin {$i-}
- BitMapError:=0; LoadLBM:=nil;
- if not OpenForInput(f,FileName) then begin
- BitMapError:=1; { File not found }
- exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- p:=malloc(64000);
- FillChar(p^,64000,0);
- seek(f,0);
- BlockRead(f,fc,12);
- if (fc.SubType<>LBM_PBM) then begin
- BitMapError:=7; { Invalid format (not BPM) }
- Free(p);
- CloseFile(f);
- exit;
- end;
- BlockRead(f,chk,8);
- if chk.ckID<>LBM_BMHD then begin
- BitMapError:=8; { Invalid format (missing BMHD) }
- Free(p);
- CloseFile(f);
- exit;
- end;
- BlockRead(f,bh,20);
- with bh do begin
- DimX:=Swap(DimX); DimY:=Swap(DimY); PosX:=Swap(PosX); PosY:=Swap(PosY);
- PageWidth:=Swap(PageWidth); PageHeight:=Swap(PageHeight);
- if (PageWidth<>320) or (PageHeight<>200) or (Planes<>8) then begin
- BitMapError:=9; { Not a 320x200/256 image }
- Free(p);
- CloseFile(f);
- exit;
- end;
- if (Compression>1) then begin
- BitMapError:=10; { Unknown compression method }
- Free(p);
- CloseFile(f);
- exit;
- end;
- end;
- BlockRead(f,chk,8);
- if (chk.ckID<>LBM_CMAP) or (SwapLong(chk.ckSize)<>768) then begin
- BitMapError:=11; { Invalid CMAP chunk }
- Free(p);
- CloseFile(f);
- exit;
- end;
- { Read palette }
- BlockRead(f,Pal,768,r);
- for r:=0 to 255 do begin
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3]:=Pal[r].r shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3+1]:=Pal[r].g shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3+2]:=Pal[r].b shr 2;
- end;
- Gata:=False;
- Repeat
- BlockRead(f,chk,8);
- if chk.ckID<>LBM_BODY then begin
- { Just skip it ... }
- Seek(f,FilePos(f)+SwapLong(chk.ckSize));
- Gata:=false;
- end else begin
- { BODY, so decompress ... }
- if bh.Compression=0 then begin
- Offset:=0;
- while bh.DimY>0 do begin
- BlockRead(f,mem[seg(p^):ofs(p^)+Offset],bh.DimX,r);
- inc(Offset,bh.PageWidth);
- dec(bh.DimY);
- end;
- Gata:=True;
- end else begin
- { RLE }
- ResetBuffer;
- Offset:=0;
- while (bh.DimY>0) do begin
- SoFar:=bh.DimX;
- if SoFar and 1 <> 0 then Inc(SoFar);
- while SoFar>0 do begin
- Value:=ShortInt(ReadByte(f));
- if Value>0 then begin
- Len:=Integer(Value)+1;
- SoFar:=SoFar-Len;
- for r:=1 to Len do begin
- Mem[seg(p^):ofs(p^)+Offset]:=ReadByte(f);
- Inc(Offset);
- end;
- end else begin
- Count:=Integer(-Value); Inc(Count);
- SoFar:=SoFar-Count;
- Value:=ShortInt(ReadByte(f));
- for r:=1 to Count do begin
- Mem[seg(p^):ofs(p^)+Offset]:=Byte(Value);
- Inc(Offset);
- end;
- end;
- end;
- dec(bh.DimY);
- Offset:=Offset+bh.PageWidth-bh.DimX;
- end;
- Gata:=True;
- end;
- end;
- if FilePos(f)>=FileSize(f) then Gata:=True;
- Until Gata;
- CloseFile(f);
- LoadLBM:=p;
- end;
-
- Procedure SaveLBM(FileName:String; PalPtr,PicPtr:Pointer);
- type
- FORM_chunk = record ckID, CkSize, SubType : LongInt end;
- Chunk = record ckID, ckSize : LongInt end;
- LBMHeader = record
- DimX, DimY, PosX, PosY : Word;
- Planes, Masking, Compression, Pad1 : Byte;
- TranspCol : Word;
- xAspect, yAspect : Byte;
- PageWidth, PageHeight : Word;
- end;
- const
- LBM_FORM = $4D524F46; { 'FORM' }
- LBM_ILBM = $4D424C49; { 'ILBM' }
- LBM_BMHD = $44484D42; { 'BMHD' }
- LBM_CMAP = $50414D43; { 'CMAP' }
- LBM_BODY = $59444F42; { 'BODY' }
- LBM_TEXT = $54584554; { 'TEXT' }
- LBM_PBM = $204D4250; { 'PBM ' }
- var
- f:file; r:word;
- k : byte;
- lulu : word;
- { File size (FORM) }
- fsz : longint;
- fszamiga : record h,l:word end absolute fsz;
- { Compressed size (BODY) }
- csz : longint;
- cszamiga : record h,l:word end absolute csz;
- fc : FORM_chunk;
- chk : Chunk;
- bh : LBMHeader;
- { Used for compression... }
- Last:Byte;
- NrOf:Word;
- Offset,AuxOffset:Word;
- aux:word;
- yo___:LongInt;
- _EOL:boolean;
- begin {$i-}
- if not OpenForOutput(f,FileName) then begin
- BitMapError:=5; { Cannot create file }
- exit;
- end;
- OutBuffIndex:=0;
- { Write FORM chunk ... }
- fc.ckID:=LBM_FORM;
- fc.SubType:={LBM_ILBM;}LBM_PBM;
- BlockWrite(f, fc, 12);
- { Write BMHD chunk ... }
- chk.ckID:=LBM_BMHD;
- chk.ckSize:=$14000000;
- BlockWrite(f,chk,8);
- { Write BitMap Header }
- bh.DimX:=Swap(320); bh.DimY:=Swap(200);
- bh.PosX:=0; bh.PosY:=0;
- bh.Planes:=8; bh.Masking:=0;
- { ++++++++++ }
- bh.Compression:=1;
- { ++++++++++ }
- bh.Pad1:=0; { Unused }
- bh.TranspCol:=Swap($BF);
- bh.xAspect:=$5; bh.yAspect:=$6;
- bh.PageWidth:=Swap(320); bh.PageHeight:=Swap(200);
- BlockWrite(f, bh, $14);
- { Write CMAP chunk }
- chk.ckID:=LBM_CMAP;
- chk.ckSize:=$00030000; { 768 (300h) in Amiga format }
- BlockWrite(f,chk,8);
- { Write palette }
- for k:=0 to 255 do begin
- WriteByte(f, mem[seg(PalPtr^):ofs(PalPtr^)+k*3] shl 2);
- WriteByte(f, mem[seg(PalPtr^):ofs(PalPtr^)+k*3+1] shl 2);
- WriteByte(f, mem[seg(PalPtr^):ofs(PalPtr^)+k*3+2] shl 2);
- end;
- FlushBuffer(f); { Flush the output buffer }
- { Write TEXT chunk and the text after it }
- chk.ckID:=LBM_TEXT;
- chk.ckSize:=$04000000;
- BlockWrite(f,chk,8);
- chk.ckID:=$4B435546; { "FUCK" }
- BlockWrite(f,chk,4);
- { Write BODY chunk }
- chk.ckID:=LBM_BODY;
- yo___:=FilePos(f);
- BlockWrite(f,chk,8);
- { Compress body with RLE }
- csz:=0;
- Offset:=0;
- OutBuffIndex:=0;
- repeat
- Last:=Mem[seg(PicPtr^):ofs(PicPtr^)+Offset];
- NrOf:=0;
- _EOL:=false;
- while (mem[seg(PicPtr^):ofs(PicPtr^)+Offset]=Last) and (Offset<64000) and
- (NrOf<127) and not _EOL do begin
- inc(NrOf); Inc(Offset);
- if Offset mod 320=0 then _EOL:=true;
- end;
- if NrOf<2 then begin
- { Uncompressed block }
- AuxOffset:=Offset-1;
- Last:=Mem[seg(PicPtr^):ofs(PicPtr^)+AuxOffset];
- NrOf:=1;
- while (Last<>Mem[seg(PicPtr^):ofs(PicPtr^)+Offset]) and (Offset<64000) and (NrOf<127) and not _EOL do begin
- inc(NrOf);
- Last:=Mem[seg(PicPtr^):ofs(PicPtr^)+Offset];
- inc(Offset);
- if Offset mod 320 = 0 then _EOL:=true;
- end;
- if (mem[seg(PicPtr^):ofs(PicPtr^)+Offset-1]=mem[seg(PicPtr^):ofs(PicPtr^)+Offset]) and (Offset<=64000) and
- (NrOf<=127) and not _EOL then begin
- dec(Offset);
- dec(NrOf); { Keeps the latest byte for a new check }
- end;
- WriteByte(f,NrOf-1); { Size of uncompressed block }
- { Write the uncompressed block ... }
- for k:=0 to NrOf-1 do WriteByte(f,Mem[seg(PicPtr^):ofs(PicPtr^)+AuxOffset+k]);
- csz:=csz+1+NrOf;
- end else begin
- WriteByte(f,Byte(-NrOf)+1); { Size of compressed block }
- WriteByte(f,Last); { Char to fill with }
- csz:=csz+2;
- end;
- if FileSize(f)>200*1024 then begin FlushBuffer(f); exit; end;
- until (Offset>=64000);
- FlushBuffer(f);
- if csz>64000 then begin
- { If it was expanded, then just store it (compression=0) }
- csz:=64000;
- seek(f,yo___+8);
- BlockWrite(f,mem[seg(PicPtr^):Ofs(PicPtr^)],64000);
- Truncate(f);
- seek(f,20);
- bh.Compression:=0;
- BlockWrite(f,bh,$14);
- end;
- { Swap up for the fuckin' Motorola CPU and write BODY chunk again }
- aux:=cszamiga.h; cszamiga.h:=cszamiga.l; cszamiga.l:=aux;
- cszamiga.l:=Swap(cszamiga.l);
- cszamiga.h:=Swap(cszamiga.h);
- Seek(f,yo___+4);
- BlockWrite(f,cszamiga,4);
- { Write FORM chunk again }
- fsz:=FileSize(f)-8;
- aux:=fszamiga.h; fszamiga.h:=fszamiga.l; fszamiga.l:=aux;
- fszamiga.l:=Swap(fszamiga.l);
- fszamiga.h:=Swap(fszamiga.h);
- Seek(f,4);
- BlockWrite(f,fszamiga,4);
- CloseFile(f); BitMapError:=0;
- end;
-
- Function LoadPIC(FileName:String; PalPtr:Pointer) : Pointer;
- Var
- f:file; p:pointer;
- head : record
- sign : word;
- xdim,ydim,xpos,ypos:word;
- bpp:byte;
- bug:byte;
- mode:char;
- ei_descr:word;
- ei_sz:word;
- end;
- bpacked,n:word;
- marker : byte;
- count : word;
- RLEb : word;
- packeds,unpackeds : word;
- remained, r : word;
- cbyte:byte;
- Offs:Word;
- x,y:integer;
- Procedure DrawRLE(count:word; b:byte);
- var k:word;
- begin
- k:=0;
- while (k<count) and (y>=0) do begin
- mem[seg(p^):ofs(p^)+(y*320+x)]:=b;
- inc(x); if x>=head.xdim then begin x:=0; dec(y) end;
- inc(k);
- end;
- end;
- begin {$i-}
- BitMapError:=0; LoadPIC:=nil;
- if not OpenForInput(f,FileName) then begin
- BitMapError:=1;
- Exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- p:=malloc(64000);
- fillchar(p^,64000,0);
- ResetBuffer;
- BlockRead(f,head,sizeof(head),r);
- if head.sign<>$1234 then begin
- BitMapError:=3; { Invalid format }
- closefile(f); Free(p);
- exit;
- end;
- if head.mode<>'L' then begin
- BitMapError:=9; { Not a 320x200/256 image }
- closefile(f); Free(p);
- exit;
- end;
- seek(f,SizeOf(head));
- if head.ei_descr=4 then BlockRead(f,PalPtr^,768,r);
- seek(f,sizeof(head)+head.ei_sz);
- blockread(f,bpacked,2,r);
- if bpacked=0 then begin
- BitMapError:=10; { Unknown compression method }
- closefile(f); Free(p);
- exit;
- end;
- {if head.ei_descr=4 then setall(@pal);}
- x:=head.xpos; y:=head.ydim-head.ypos-1;
- for n:=1 to bpacked do begin
- { Unpack each block ... }
- PackedS:=Word(ReadByte(f));
- PackedS:=PackedS+(ReadByte(f) shl 8);
- UnPackedS:=ReadByte(f);
- UnPackedS:=UnPackedS+(ReadByte(f) shl 8);
- marker:=ReadByte(f);
- Remained:=PackedS-5; { 5 = 2 (PackedS) + 2 (UnPackedS) + 1 (Marker) }
- while Remained>0 do begin
- cbyte:=ReadByte(f); dec(Remained);
- if cbyte<>marker then begin
- mem[seg(p^):ofs(p^)+(y*320+x)]:=cbyte;
- inc(x); if x>=head.xdim then begin x:=0; dec(y) end;
- end else begin
- cbyte:=ReadByte(f); dec(Remained);
- if cbyte<>0 then
- Count:=cbyte
- else begin
- Count:=ReadByte(f);
- Count:=Count+(ReadByte(f) shl 8);
- dec(Remained,2);
- end;
- RLEb:=ReadByte(f);
- Dec(Remained);
- DrawRLE(Count,RLEb);
- end;
- end;
- end;
- CloseFile(f);
- BitMapError:=0; LoadPIC:=p;
- end;
-
- Function LoadPCX(FileName:String; PalPtr:Pointer) : Pointer;
- type
- PCXHType = record
- Manufacturer : byte; { Always =10 for Paintbrush }
- Version : byte; { Version information }
- Encoding : byte; { Run-length encoding (=???) }
- BitsPerPixel : byte; { Bits per pixel }
- MinX : word; { Picture dimensions (incl) }
- MinY : word; { }
- MaxX : word; { }
- MaxY : word; { }
- HorizRes : word; { Display horiz resolution }
- VertRes : word; { Display vert resolution }
- Pal16 : array[0..47] of byte; { Pallete }
- VMode : byte; { (ignored,=0) }
- ColPlanes : byte; { Number of planes (ver 2.5=0)}
- BytesPerLine : word; { Bytes per line }
- PalInfo : word; { Palette Info (1=col, 2=gray)}
- shres : word; { Scanner resolution }
- svres : word; { }
- xtra : array[0..54] of byte; { Extra space (filler) }
- end;
- var
- Pal:Array[byte] of record r,g,b:byte end;
- f:file; p:pointer;
- bh:PCXHType;
- r:word; palsgn:byte;
- Gata:boolean;
- Offset:Word;
- Value,Counter:Byte;
- y,x,xx:integer;
- begin {$i-}
- BitMapError:=0; LoadPCX:=nil;
- if not OpenForInput(f,FileName) then begin
- BitMapError:=1; { File not found }
- exit;
- end;
- if mavail<64000 then begin
- BitMapError:=2; { Not enough memory }
- CloseFile(f);
- exit;
- end;
- p:=malloc(64000);
- FillChar(p^,64000,0);
- seek(f,0);
- BlockRead(f,bh,sizeof(bh),r);
- with bh do begin
- if (BitsPerPixel<>8) or (MaxX>320) or (MaxY>200) then begin
- BitMapError:=9; { Not a 320x200/256 image }
- Free(p);
- CloseFile(f);
- exit;
- end;
- if (Encoding<>1) then begin
- BitMapError:=10; { Unknown compression method }
- Free(p);
- CloseFile(f);
- exit;
- end;
- end;
- seek(f,filesize(f)-769);
- BlockRead(f,PalSgn,1,r);
- if PalSgn<>12 then begin
- BitMapError:=12; { Invalid palette (PCX) }
- Free(p);
- CloseFile(f);
- exit;
- end;
- { Read palette }
- BlockRead(f,Pal,768,r);
- for r:=0 to 255 do begin
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3]:=Pal[r].r shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3+1]:=Pal[r].g shr 2;
- mem[seg(PalPtr^):ofs(PalPtr^)+r*3+2]:=Pal[r].b shr 2;
- end;
- Gata:=False;
- { RLE }
- Seek(f,sizeof(bh)-1); { ??? }
- ResetBuffer;
- Offset:=0;
- for y:=0 to bh.MaxY do begin
- xx:=bh.MaxX+1;
- repeat
- value:=ReadByte(f);
- if value and $C0 = $C0 then begin
- { Run the counter }
- Counter:=Value and $3F;
- Value:=ReadByte(f);
- for x:=1 to Counter do begin
- Mem[seg(p^):ofs(p^)+Offset]:=Value;
- inc(Offset); dec(xx);
- end;
- end else begin
- Mem[seg(p^):ofs(p^)+Offset]:=Value;
- inc(Offset); dec(xx);
- end;
- until xx<=0;
- inc(Offset,320-bh.MaxX-1);
- end;
- CloseFile(f);
- LoadPCX:=p;
- end;
-
- { Special functions }
-
- Procedure MovePicToXMS(PalPtr:pointer; var PicPtr:Pointer; var Handle:word);
- begin
- AllocXMS(Handle,64);
- CopyToXMS(PalPtr^,Handle,0,768);
- CopyToXMS(PicPtr^,Handle,768,64000);
- Free(PicPtr);
- PicPtr:=nil;
- end;
-
- Procedure CopyPicToXMS(PalPtr,PicPtr:Pointer; var Handle:word);
- begin
- AllocXMS(Handle,64);
- CopyToXMS(PalPtr^,Handle,0,768);
- CopyToXMS(PicPtr^,Handle,768,64000);
- end;
-
- Procedure CopyPicFromXMS(PalPtr:pointer; var PicPtr:Pointer; var Handle:word);
- begin
- CopyFromXMS(Handle,0,PalPtr^,768);
- if PicPtr=nil then begin
- PicPtr:=malloc(64000);
- end;
- CopyFromXMS(Handle,768,PicPtr^,64000);
- end;
-
- Procedure MovePicFromXMS(PalPtr:pointer; var PicPtr:Pointer; var Handle:word);
- begin
- CopyFromXMS(Handle,0,PalPtr^,768);
- if PicPtr=nil then begin
- PicPtr:=malloc(64000);
- end;
- CopyFromXMS(Handle,768,PicPtr^,64000);
- FreeXMS(Handle);
- end;
-
- Begin
- End.
-